﻿using FlyingEye.Come;
using FlyingEye.Come.Repositories;
using FlyingEye.ComeServices;
using FlyingEye.ComServices;
using FlyingEye.DeviceMaintenance;
using FlyingEye.DeviceMaintenance.Repositories;
using FlyingEye.DeviceMaintenanceServices;
using FlyingEye.Factories;
using FlyingEye.HttpServices;
using FlyingEye.HttpServices.Requests;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Application.Services;

namespace FlyingEye.MonitorService
{
    /// <summary>
    /// 部件运行监控服务
    /// </summary>
    public class DevicePartRuntimeMonitorService : ApplicationService
    {
        private readonly IDevicePartRepository _devicePartRepository;

        private readonly IDevicePartCharacteristicRepository _devicePartCharacteristicRepository;

        private readonly DeviceHubService _deviceHubService;

        private readonly IDeviceHostRepository _deviceHostRepository;

        private readonly IDeviceMaintenanceRepository _deviceMaintenanceRepository;

        private readonly IComeGroupNotificationConfigurationRepository _comeGroupNotificationConfigurationRepository;

        private readonly ComeNotificationService _comeNotificationService;

        private readonly ILogger<DevicePartRuntimeMonitorService> _logger;

        public DevicePartRuntimeMonitorService(
            IDevicePartRepository devicePartRepository,
            IDevicePartCharacteristicRepository devicePartCharacteristicRepository,
            IDeviceHostRepository deviceHostRepository,
            IDeviceMaintenanceRepository deviceMaintenanceRepository,
            DeviceHubService deviceHubService,
            ComeNotificationService comeNotificationService,
            IComeGroupNotificationConfigurationRepository comeGroupNotificationConfigurationRepository,
            ILogger<DevicePartRuntimeMonitorService> logger)
        {
            _devicePartRepository = devicePartRepository;
            _devicePartCharacteristicRepository = devicePartCharacteristicRepository;
            _deviceHostRepository = deviceHostRepository;
            _deviceMaintenanceRepository = deviceMaintenanceRepository;
            _deviceHubService = deviceHubService;
            _comeNotificationService = comeNotificationService;
            _comeGroupNotificationConfigurationRepository = comeGroupNotificationConfigurationRepository;
            _logger = logger;
        }

        /// <summary>
        /// 对所有的部件执行运行时间监控更新
        /// </summary>
        public async Task ExecuteMonitorTasksAsync()
        {
            int pageIndex = 0; // 假设从 0 开始
            const int pageSize = 100;

            // 重置任务状态令牌

            while (true)
            {
                var deviceHosts = await _deviceHostRepository.GetPagedListAsync(
                    skipCount: pageIndex * pageSize, // 确认 pageIndex 起始值
                    maxResultCount: pageSize,
                    sorting: "Id" // 确保 Id 有索引
                );

                if (!deviceHosts.Any())
                {
                    break;
                }

                foreach (var deviceHost in deviceHosts)
                {
                    await ExecuteMonitorTasksByDeviceHostAsync(ObjectMapper.Map<DeviceHostModel, DeviceHostResponse>(deviceHost));
                }

                // 更新分页索引
                pageIndex++;
            }
        }

        private async Task ExecuteMonitorTasksByDeviceHostAsync(DeviceHostResponse deviceHost)
        {
            int pageIndex = 0; // 假设从 0 开始
            const int pageSize = 100;

            // 重置任务状态令牌

            while (true)
            {
                var query = await _deviceMaintenanceRepository.GetQueryableAsync();
                var maintenances = await query.Where(item => item.DeviceHostId == deviceHost.Id)
                    .OrderBy(item => item.Id)
                    .Skip(pageIndex * pageSize)
                    .Take(pageSize)
                    .ToListAsync();

                if (!maintenances.Any())
                {
                    break;
                }

                foreach (var maintenance in maintenances)
                {
                    await ExecuteMonitorTasksByDeviceMaintenanceAsync(deviceHost, ObjectMapper.Map<DeviceMaintenanceModel, DeviceMaintenanceResponse>(maintenance));
                }

                // 更新分页索引
                pageIndex++;
            }
        }

        private async Task ExecuteMonitorTasksByDeviceMaintenanceAsync(
            DeviceHostResponse deviceHost,
            DeviceMaintenanceResponse maintenance)
        {
            int pageIndex = 0; // 假设从 0 开始
            const int pageSize = 100;

            // 重置任务状态令牌

            while (true)
            {
                var query = await _devicePartRepository.GetQueryableAsync();
                var parts = await query.Where(item => item.DeviceMaintenanceId == maintenance.Id)
                    .OrderBy(item => item.Id)
                    .Skip(pageIndex * pageSize)
                    .Take(pageSize)
                    .ToListAsync();

                if (!parts.Any())
                {
                    break;
                }

                foreach (var part in parts)
                {
                    var runtime = await TryGetDevicePartRuntimeAsync(deviceHost.DeviceHostName, maintenance, part.Id);

                    // 更新部件运行时间
                    if (runtime != null)
                    {
                        part.CurrentLifetime = runtime.CurrentLifetime;
                        part.AccumulatedDowntime = runtime.AccumulatedDowntime;
                        part.EconomicLifetimeThreshold = runtime.EconomicLifetimeThreshold;
                        await _devicePartRepository.UpdateAsync(part);

                        var message = $"# 设备部件运行信息\n\n* 设备主机：{deviceHost.DeviceHostName}\n\n* 设备名称：{maintenance.DeviceName}\n\n* 部件名称：{part.DevicePartName}\n\n* 停机寿命：{part.AccumulatedDowntime}\n\n* 当前寿命：{part.CurrentLifetime}\n\n* 经济寿命：{part.EconomicLifetimeThreshold}";
                        await NotifyMessageAsync(maintenance.ComeGroupNotificationConfigurationId, "设备部件运行信息", message);
                    }
                }

                // 更新分页索引
                pageIndex++;
            }
        }

        private static Dictionary<string, string> CharacteristicMapping = new()
            {
                { "停机寿命", "" },
                { "当前寿命", "" },
                { "经济寿命", "" }
            };

        private async Task NotifyMessageAsync(
            Guid? comeGroupNotificationConfigurationId,
            string title,
            string message)
        {
            if (!comeGroupNotificationConfigurationId.HasValue)
            {
                return;
            }

            var groupModel = await _comeGroupNotificationConfigurationRepository.FindAsync
                   (item => item.Id == comeGroupNotificationConfigurationId);

            if (groupModel != null)
            {
                try
                {
                    await _comeNotificationService.NotifyAsync(
                   ObjectMapper.Map<ComeGroupNotificationConfigurationModel, ComeGroupNotificationConfiguration>(groupModel),
                   new ComeGroupNotification(
                       title,
                       message));
                }
                catch (Exception err)
                {
                    _logger.LogError(err, "发送 COME 通知失败。");
                }
            }
        }

        /// <summary>
        /// 尝试获取设备部件运行时间
        /// </summary>
        private async Task<DeviceRuntime?> TryGetDevicePartRuntimeAsync(
            string resourceId,
            DeviceMaintenanceResponse deviceMaintenance,
            Guid devicePartId)
        {
            var characteristicList = await _devicePartCharacteristicRepository.GetListAsync(item =>
            item.DevicePartId == devicePartId
            &&
            (item.CharacteristicName == "停机寿命"
            || item.CharacteristicName == "当前寿命"
            || item.CharacteristicName == "经济寿命"));

            if (characteristicList.Count != 3)
            {
                await NotifyMessageAsync(
                    deviceMaintenance.ComeGroupNotificationConfigurationId,
                    "部件寿命通知提示",
                     $"# 用户部件配置提示\n\n设备主机 **{resourceId}** 的 **{deviceMaintenance.DeviceName}** 设备未完成配置寿命特征点，请联系管理员完成配置。"
                    );
                return null;
            }

            foreach (var item in characteristicList)
            {
                var result = await _deviceHubService.ReadNumericValeuAsync(resourceId,
                new ReadNumericValueRequest(deviceMaintenance.DeviceName, item.Address, item.DateType));

                if (!result.IsSuccess)
                {
                    await NotifyMessageAsync(deviceMaintenance.ComeGroupNotificationConfigurationId,
                        "读取寿命信息错误",
                        $"# 读取寿命信息错误\n\n## 详细错误信息\n\n* 设备主机：{resourceId}\n\n* 逻辑设备：{deviceMaintenance.DeviceName}\n\n* 地址：{item.Address}\n\n* 数据类型：{item.DateType}\n\n* 错误信息：{result.Message}");
                    return null;
                }

                CharacteristicMapping[item.CharacteristicName] = result.Value!;
            }

            return new DeviceRuntime
            {
                CurrentLifetime = int.Parse(CharacteristicMapping["当前寿命"]),
                AccumulatedDowntime = int.Parse(CharacteristicMapping["停机寿命"]),
                EconomicLifetimeThreshold = int.Parse(CharacteristicMapping["停机寿命"]) - int.Parse(CharacteristicMapping["经济寿命"])
            };
        }
    }
}
